package com.orange.cetback.common.utils;

import com.orange.cetback.pojo.entity.UserWordReview;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Random;

/**
 * SM-2 间隔重复算法工具类
 */
public class SMT2Util {
    // 算法常量配置
    private static final BigDecimal EASE_FACTOR_MIN = new BigDecimal("1.3");
    private static final BigDecimal EASE_FACTOR_INITIAL = new BigDecimal("2.5");
    private static final BigDecimal EASE_FACTOR_INCREMENT = new BigDecimal("0.1");
    private static final BigDecimal EASE_FACTOR_PENALTY = new BigDecimal("0.5");
    private static final double INTERVAL_RANDOM_RANGE = 0.1; // ±10%波动
    private static final Random RANDOM = new Random();

    /**
     * 更新复习数据（根据用户回答正确性）
     * @param review   用户单词复习记录
     * @param isCorrect 本次回答是否正确
     */
    public static void updateReviewData(UserWordReview review, boolean isCorrect) {
        // 公共字段更新
        review.setLastReviewTime(LocalDateTime.now());
        review.setLastReviewResult(isCorrect ? (byte) 1 : (byte) 0);
        review.setTotalReviews(review.getTotalReviews() + 1);

        if (isCorrect) {
            handleCorrectAnswer(review);
        } else {
            handleIncorrectAnswer(review);
        }

        // 边界保护
        clampEaseFactor(review);
        // 添加间隔随机性
        applyIntervalRandomness(review);
        // 更新下次复习日期
        review.setNextReviewDate(LocalDate.now().plusDays(review.getIntervalStage()));
    }

    private static void handleCorrectAnswer(UserWordReview review) {
        // 连续正确次数+1
        review.setConsecutiveCorrect(review.getConsecutiveCorrect() + 1);

        // 间隔阶段计算
        int newInterval = switch (review.getConsecutiveCorrect()) {
            case 1 -> 1;   // 首次正确：1天
            case 2 -> 6;   // 第二次正确：6天
            case 3 -> 14;  // 第三次正确：14天
            default -> (int) (review.getIntervalStage() * review.getEaseFactor().doubleValue());
        };
        review.setIntervalStage(newInterval);

        // 易度因子调整（答对时逐步增加）
        review.setEaseFactor(review.getEaseFactor().add(EASE_FACTOR_INCREMENT));
    }

    private static void handleIncorrectAnswer(UserWordReview review) {
        // 重置连续正确次数
        review.setConsecutiveCorrect(0);
        // 回退到最低间隔阶段
        review.setIntervalStage(1);
        // 惩罚性降低易度因子
        review.setEaseFactor(review.getEaseFactor().subtract(EASE_FACTOR_PENALTY));
    }

    private static void clampEaseFactor(UserWordReview review) {
        if (review.getEaseFactor().compareTo(EASE_FACTOR_MIN) < 0) {
            review.setEaseFactor(EASE_FACTOR_MIN);
        }
    }

    private static void applyIntervalRandomness(UserWordReview review) {
        // 生成 ±10% 随机波动
        double randomFactor = 1 + (RANDOM.nextDouble() * 2 * INTERVAL_RANDOM_RANGE - INTERVAL_RANDOM_RANGE);
        int newInterval = (int) Math.round(review.getIntervalStage() * randomFactor);
        // 确保间隔至少1天
        review.setIntervalStage(Math.max(newInterval, 1));
    }

    /**
     * 初始化新词的复习数据（首次学习时调用）
     */
    public static void initNewWordReview(UserWordReview review) {
        review.setIntervalStage(1);        // 新词阶段
        review.setTotalReviews(0);
        review.setEaseFactor(EASE_FACTOR_INITIAL);
        review.setConsecutiveCorrect(0);
        review.setCreateTime(LocalDateTime.now());
    }
}
